{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Photoshop-like Functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#Table of Contents\n", "* [1. Photoshop-like Functions](#1.-Photoshop-like-Functions)\n", "\t* [1.1 Green screen Effects - Chroma Key Compositing](#1.1-Green-screen-Effects---Chroma-Key-Compositing)\n", "\t* [1.2 Obamicon](#1.2-Obamicon)\n", "\t* [1.3 Edge Detection](#1.3-Edge-Detection)\n", "\t* [1.4 Blurring](#1.4-Blurring)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1 Green screen Effects - Chroma Key Compositing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "https://en.wikipedia.org/wiki/Chroma_key\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloaded 'greenscreen1.jpg'.\n" ] } ], "source": [ "%download http://blog.unem.de/wp-content/uploads/2012/05/11-Greenscreen-Clarissa-Knorr.jpg -f greenscreen1.jpg" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " Sketch #10:
\n", "
\n", "
\n", "
\n", " \n", " \n", " \n", " \n", "
\n", "Sketch #10 state: Loading...
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "/* @pjs preload=\"greenscreen1.jpg\"; */\n", "\n", "PImage img;\n", "\n", "void setup() {\n", " img = loadImage(\"greenscreen1.jpg\");\n", " // println(\"\" + img.width + \" x \" + img.height)\n", " // 1920 x 1080\n", " // Resize to a more reasonable size:\n", " img.resize(img.width/10.0, img.height/10.0);\n", " // Make sketch size match:\n", " size(img.width, img.height);\n", "}\n", "\n", "void draw() {\n", " image(img, 0, 0);\n", " noLoop();\n", "}" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " Sketch #11:
\n", "
\n", "
\n", "
\n", " \n", " \n", " \n", " \n", "
\n", "Sketch #11 state: Loading...
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "/* @pjs preload=\"greenscreen1.jpg\"; */\n", "\n", "PImage img;\n", "\n", "void setup() {\n", " img = loadImage(\"greenscreen1.jpg\");\n", " // println(\"\" + img.width + \" x \" + img.height)\n", " // 1920 x 1080\n", " // Resize to a more reasonable size:\n", " img.resize(img.width/10.0, img.height/10.0);\n", " // Make sketch size match:\n", " size(img.width, img.height);\n", " // Add this to get pixel information into array:\n", " loadPixels(img);\n", "}\n", "\n", "void draw() {\n", " image(img, 0, 0);\n", " noLoop();\n", "}\n", "\n", "void mousePressed() {\n", " color pixel = img.pixels[mouseX + mouseY * img.width];\n", " println(\"Color: \" + red(pixel) + \", \" + green(pixel) + \", \" + blue(pixel));\n", "}" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloaded 'background1.jpg'.\n" ] } ], "source": [ "%download http://images.tenplay.com.au/~/media/News/National%20News/National%20News%20do%20not%20delete/News_National_showheader_480x210.jpg -f background1.jpg" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " Sketch #12:
\n", "
\n", "
\n", "
\n", " \n", " \n", " \n", " \n", "
\n", "Sketch #12 state: Loading...
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "/* @pjs preload=\"greenscreen1.jpg,background1.jpg\"; */\n", "\n", "PImage img;\n", "PImage background;\n", "PImage composite;\n", "\n", "void setup() {\n", " img = loadImage(\"greenscreen1.jpg\");\n", " img.resize(img.width/10.0, img.height/10.0);\n", " size(img.width, img.height);\n", " // get background:\n", " background = loadImage(\"background1.jpg\");\n", " background.resize(img.width, img.height);\n", " // Now we image processing:\n", " composite = new PImage(img.width, img.height);\n", " loadPixels(background);\n", " loadPixels(img);\n", " loadPixels(composite);\n", " for (int i = 0; i < composite.width; i++) {\n", " for (int j = 0; j < composite.height; j++) {\n", " // if pixel is green, get it from background\n", " // else get it from foreground\n", " composite.pixels[i + j * composite.width] = img.pixels[i + j * img.width];\n", " }\n", " }\n", " updatePixels(composite);\n", "}\n", "\n", "void mousePressed() {\n", " color pixel = img.pixels[mouseX + mouseY * img.width];\n", " println(\"Color: \" + red(pixel) + \", \" + green(pixel) + \", \" + blue(pixel));\n", "}\n", "\n", "void draw() {\n", " image(composite, 0, 0);\n", "}" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " Sketch #13:
\n", "
\n", "
\n", "
\n", " \n", " \n", " \n", " \n", "
\n", "Sketch #13 state: Loading...
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "/* @pjs preload=\"greenscreen1.jpg,background1.jpg\"; */\n", "\n", "PImage img;\n", "PImage background;\n", "PImage composite;\n", "\n", "void setup() {\n", " img = loadImage(\"greenscreen1.jpg\");\n", " img.resize(img.width/10.0, img.height/10.0);\n", " size(img.width, img.height);\n", " // get background:\n", " background = loadImage(\"background1.jpg\");\n", " background.resize(img.width, img.height);\n", " // Now we image processing:\n", " composite = new PImage(img.width, img.height);\n", " loadPixels(background);\n", " loadPixels(img);\n", " loadPixels(composite);\n", " for (int i = 0; i < composite.width; i++) {\n", " for (int j = 0; j < composite.height; j++) {\n", " color pixel = img.pixels[i + j * img.width];\n", " int r = red(pixel);\n", " int g = green(pixel);\n", " int b = blue(pixel);\n", " // if pixel is green, get it from background\n", " if (r < 55 && g < 170 && g > 145 && b > 50 && b < 80) {\n", " composite.pixels[i + j * composite.width] = background.pixels[i + j * img.width];\n", " } else {\n", " // else get it from foreground\n", " composite.pixels[i + j * composite.width] = pixel;\n", " }\n", " }\n", " }\n", " updatePixels(composite);\n", "}\n", "\n", "void mousePressed() {\n", " color pixel = img.pixels[mouseX + mouseY * img.width];\n", " println(\"Color: \" + red(pixel) + \", \" + green(pixel) + \", \" + blue(pixel));\n", "}\n", "\n", "void draw() {\n", " image(composite, 0, 0);\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Problem 1**: fix the green screen effect above to make the background a nice, uninterrupted image without any green showing through.\n", "\n", "**Problem 2**: Make your own \"green screen\" effect using your own pictures. Use a colored blanket, for example, as your background. Do something other than a news cast simulation. For example, put yourself in an unexpected place." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.2 Obamicon" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "\n", "**Problem 3**: Take the regular picture of Obama and see if you can produce one programmatically that looks like the artistic version.\n", "\n", "**Problem 4**: Take a pictures of yourself, and make it look like an Obamicon-ified version." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.3 Edge Detection" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "https://processing.org/examples/edgedetection.html\n", "\n", "There are a series of image processing techniques that can be accomplished by comparing a pixel to its surrounding 8 pixels.\n", "\n", "A sample kernel for edge detection (high-pass filter):\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", " \n", " \n", " \n", "\n", "
-1-1-1
-1+9-1
-1-1-1
" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloaded 'moon.jpg'.\n" ] } ], "source": [ "%download https://processing.org/examples/moon.jpg" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " Sketch #14:
\n", "
\n", "
\n", "
\n", " \n", " \n", " \n", " \n", "
\n", "Sketch #14 state: Loading...
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "// The next line is needed if running in JavaScript Mode with Processing.js\n", "/* @pjs preload=\"moon.jpg\"; */\n", "\n", "float[][] kernel = {{ -1, -1, -1}, \n", " { -1, 9, -1}, \n", " { -1, -1, -1}};\n", " \n", "PImage img;\n", "\n", "void setup() { \n", " size(640, 360);\n", " img = loadImage(\"moon.jpg\"); // Load the original image\n", "}\n", "\n", "void draw() {\n", " image(img, 0, 0); // Displays the image from point (0,0) \n", " img.loadPixels();\n", " // Create an opaque image of the same size as the original\n", " PImage edgeImg = createImage(img.width, img.height, RGB);\n", " // Loop through every pixel in the image.\n", " for (int y = 1; y < img.height-1; y++) { // Skip top and bottom edges\n", " for (int x = 1; x < img.width-1; x++) { // Skip left and right edges\n", " float sum = 0; // Kernel sum for this pixel\n", " for (int ky = -1; ky <= 1; ky++) {\n", " for (int kx = -1; kx <= 1; kx++) {\n", " // Calculate the adjacent pixel for this kernel point\n", " int pos = (y + ky)*img.width + (x + kx);\n", " // Image is grayscale, red/green/blue are identical\n", " float val = red(img.pixels[pos]);\n", " // Multiply adjacent pixels based on the kernel values\n", " sum += kernel[ky+1][kx+1] * val;\n", " }\n", " }\n", " // For this pixel in the new image, set the gray value\n", " // based on the sum from the kernel\n", " edgeImg.pixels[y*img.width + x] = color(sum, sum, sum);\n", " }\n", " }\n", " // State that there are changes to edgeImg.pixels[]\n", " edgeImg.updatePixels();\n", " image(edgeImg, width/2, 0); // Draw the new image\n", " noLoop();\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Problem 5**: Try edge detection on one of your own images, but with a purpose. What is the use of edge detection?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.4 Blurring" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "https://processing.org/examples/blur.html\n", "\n", "A sample kernel for blurring (low-pass filter):\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", " \n", " \n", " \n", "\n", "
1/91/91/9
1/91/91/9
1/91/91/9
" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " Sketch #15:
\n", "
\n", "
\n", "
\n", " \n", " \n", " \n", " \n", "
\n", "Sketch #15 state: Loading...
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "// The next line is needed if running in JavaScript Mode with Processing.js\n", "/* @pjs preload=\"moon.jpg\"; */ \n", "\n", "float v = 1.0 / 9.0;\n", "float[][] kernel = {{ v, v, v }, \n", " { v, v, v }, \n", " { v, v, v }};\n", " \n", "PImage img;\n", "\n", "void setup() {\n", " size(640, 360);\n", " img = loadImage(\"moon.jpg\"); // Load the original image\n", "} \n", "\n", "void draw() {\n", " image(img, 0, 0); // Displays the image from point (0,0) \n", " img.loadPixels();\n", "\n", " // Create an opaque image of the same size as the original\n", " PImage edgeImg = createImage(img.width, img.height, RGB);\n", "\n", " // Loop through every pixel in the image\n", " for (int y = 1; y < img.height-1; y++) { // Skip top and bottom edges\n", " for (int x = 1; x < img.width-1; x++) { // Skip left and right edges\n", " float sum = 0; // Kernel sum for this pixel\n", " for (int ky = -1; ky <= 1; ky++) {\n", " for (int kx = -1; kx <= 1; kx++) {\n", " // Calculate the adjacent pixel for this kernel point\n", " int pos = (y + ky)*img.width + (x + kx);\n", " // Image is grayscale, red/green/blue are identical\n", " float val = red(img.pixels[pos]);\n", " // Multiply adjacent pixels based on the kernel values\n", " sum += kernel[ky+1][kx+1] * val;\n", " }\n", " }\n", " // For this pixel in the new image, set the gray value\n", " // based on the sum from the kernel\n", " edgeImg.pixels[y*img.width + x] = color(sum);\n", " }\n", " }\n", " // State that there are changes to edgeImg.pixels[]\n", " edgeImg.updatePixels();\n", "\n", " image(edgeImg, width/2, 0); // Draw the new image\n", " noLoop();\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Problem 6**: Perform blurring on one of your own images. Why might this be useful?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Bonus**: combine two of the photoshop-like effects in a single image." ] } ], "metadata": { "kernelspec": { "display_name": "Calysto Processing", "language": "processing", "name": "calysto_processing" }, "language_info": { "codemirror_mode": { "name": "text/x-java", "version": 2 }, "file_extension": ".java", "mimetype": "text/x-java", "name": "java" } }, "nbformat": 4, "nbformat_minor": 0 }